# -*- coding: utf-8 -*-
"""
Created on Fri Nov 29 11:02:06 2024

@author: DELL
"""
#交换两个值的函数
def swap(a, b):
    return b, a
"""
初始化数据表S和根据密钥填充数据表T

 S: 长度为256的列表，用于存储相关数据，将被初始化为0到255
key: 用于填充T表的密钥，
return: 初始化后的S列表和填充后的T列表
"""
def init(S, key):
    lenkey = len(key)
    for i in range(256):
        S[i] = i
        T[i] = int(key[i % lenkey])
    #print(S,T)
    return S, T

def transform(S, T):
    """
    对数据表S和T进行置换的操作

    S: 长度为256的列表，用于存储相关数据，元素应为整数类型
    T: 长度为256的列表，用于存储相关数据，元素应为整数类型
    """
    j = 0
    for i in range(256):
        # 确保S和T中的元素为整数类型进行相加操作，计算j的值
        j = (j + int(S[i]) + int(T[i])) % 256
        S[i], S[j] = swap(S[i], S[j])
        #print(S,T)


def keyflow(S, lendata):
    """
    
    S: 经过初始化和可能的置换操作后的长度为256的列表，用于生成密钥流
    lendata: 需要生成的密钥流的长度，通常与要处理的数据长度相关
    return: 生成的密钥流，以列表形式返回
    """
    flow = [0] * lendata
    i = j = 0
    for f in range(lendata):
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = swap(S[i], S[j])
        t = (S[i] + S[j]) % 256
        flow[f] = S[t]
    return flow


def crypt(data, flow):
    """
    使用密钥流对数据进行加密或解密操作

    data: 要进行加密或解密的数据，这里假设是整数列表，可根据实际情况修改
    flow: 用于加密或解密的密钥流，由keyflow函数生成，元素应为整数类型
    return: 加密或解密后的数据，以列表形式返回
    """
    encrypted_data = []
    for i in range(len(data)):
        encrypted_data.append(data[i] ^ flow[i])
    return encrypted_data


if __name__ == "__main__":
    """
    主函数，程序的入口点，用于调用其他函数完成数据的加密、解密操作并输出结果
    """

    # 获取用户输入的密钥，假设用户输入数字组成的字符串，可根据实际情况修改提示信息
    k = input("请输入加密密钥（数字组成的字符串形式）：")

    # 获取用户输入的要加密的文本，将每个字符转换为其对应的ASCII码值组成列表
    data_str = input("请输入要加密的文本：")
    data = [ord(char) for char in data_str]

    S = [0] * 256
    T = [0] * 256

    S, T = init(S, k)
    transform(S, T)
    flow = keyflow(S, len(data))
    encrypted_data = crypt(data, flow)
    decrypted_data = crypt(encrypted_data, flow)

    # 将加密后的数据转换为二进制形式并输出
    encrypted_data_bin = ''.join([bin(code)[2:].zfill(8) for code in encrypted_data])
    print("原始数据:", data_str)
    print("加密后数据（二进制形式）:", encrypted_data_bin)
    print("解密后数据:", ''.join([chr(code) for code in decrypted_data]))